package com.rui.strategy.main;

import com.rui.strategy.model.VipCardFactory;
import com.rui.strategy.model.Order;

/**
 * 策略模式（Strategy Pattern）
 * <p>
 * <p>
 * 策略模式又叫政策模式（Policy Pattern），它是将定义的算法家族分别封装起来，让它们之间可以互相替换，从而让算法的变化不会影响到使用算法的用户。可以避免多重分支的if......else和switch语句。
 * <p>
 * 策略模式的主要角色如下：
 * <p>
 * 抽象策略（Strategy）类：这是一个抽象角色，通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
 * 具体策略（Concrete Strategy）类：实现了抽象策略定义的接口，提供具体的算法实现或行为。
 * 环境（Context）类：持有一个策略类的引用，最终给客户端调用。
 * <p>
 * <p>
 * 适用场景：
 * 系统中有很多类，而它们的区别仅仅在于它们的行为不同。
 * 系统需要动态地在几种算法中选择一种。
 * 需要屏蔽算法规则。
 * <p>
 * 优点：
 * 符合开闭原则。
 * 避免使用多重条件语句。
 * 可以提高算法的保密性和安全性。
 * 易于扩展。
 * <p>
 * 缺点：
 * 客户端必须知道所有的策略，并且自行决定使用哪一个策略类。
 * 代码中会产生非常多的策略类，增加维护难度。
 *
 * @author ZhangRui
 * @date 2023/03/03 13:38
 **/
public class Main {

    public static void main(String[] args) {

        // 测试会员卡
        testCard();

        // 测试支付
        testPay();
    }

    private static void testCard() {
        //金卡打7折
        VipCardFactory.getVIPCard("gold").discount();
        //银卡打8折
        VipCardFactory.getVIPCard("silver").discount();
        //普通会员没有折扣
        VipCardFactory.getVIPCard("other").discount();
    }

    private static void testPay() {
        Order order = new Order("20221014001", 500);
        //欢迎使用微信支付
        //本次交易金额:500.0,开始扣款...
        //支付失败!余额不足!欠200.0元!
        System.out.println(order.pay("WeChat"));
        //欢迎使用支付宝
        //本次交易金额:500.0,开始扣款...
        //支付成功!支付金额:500.0余额剩余:0.0
        System.out.println(order.pay("Ali"));
        //欢迎使用现金支付
        //本次交易金额:500.0,开始扣款...
        //支付成功!支付金额:500.0余额剩余:500.0
        System.out.println(order.pay());
    }
}
